<?php

namespace builder\helper;

use yii\base\DynamicModel;

/**
 * 数据合法性校验，基于底层模型【DynamicModel】
 *
 * 用法：
 *
 * ```php
 * $model = Validation::data($queryParams, [
 *      ['mobile', 'required'],
 *      [['state', 'sex'], 'in', 'range' => [1, 2]],
 *  ], ['mobile' => '手机号', 'state' => '状态', 'sex' => '性别']);
 * if ($model->isHasError) {
 *     return $this->asFail($model->firstErrorSummary);
 * }
 *
 * ```
 *
 * @property-read boolean isHasError 是否存在校验错误信息
 * @property-read string firstErrorSummary 校验错误信息，不存在错误信息，则默认为"Unknown Error."
 *
 */
class Validation extends DynamicModel
{
    /**
     * 重构【DynamicModel】中`validateData`方法，添加了支持字段标签定义
     * @param array $data 待校验数据
     * @param array $rules 数据校验规则
     * @param array $attributeLabels 定义属性标签名
     * @param Validation|null $context 上下文模型实例
     * @return $this
     */
    public static function data(array $data, array $rules, array $attributeLabels = [], ?Validation $context = null)
    {
        $model = $context ?: (new static());
        //设置属性标签
        $model->setAttributeLabels($attributeLabels);
        //添加对象属性和属性验证规则
        foreach ($rules as $rule) {
            $model->addRule($rule[0], $rule[1], array_slice($rule, 2));
        }

        //安全（场景：`default`）加载表单数据。
        $model->load($data, '');
        $model->validate();

        return $model;
    }

    /**
     * 是否存在校验错误
     * @return bool
     */
    public function getIsHasError()
    {
        return $this->hasErrors();
    }

    /**
     * 获取第一个错误摘要信息
     * @param string $defaultErrorMessage
     * @return string
     */
    public function getFirstErrorSummary($defaultErrorMessage = 'Unknown Error.')
    {
        $firstErrors = $this->firstErrors;
        return reset($firstErrors) ?: $defaultErrorMessage;
    }
}